//
//  UIView+WebCache.m
//  ZYWebImage
//
//  Created by wzp on 2025/3/29.
//

#import "UIView+WebCache.h"
#import <objc/runtime.h>
#import "IZYWebImageProtocol.h"
#import "ZYWebImageManager.h"
static char *const kLastLoadingUrlKey;
static char *const kTasksDictKey;

typedef NSMapTable<NSString *, id<IZYTaskProtocol>> ZYTasksDictionary;
@implementation UIView (WebCache)
- (NSURL *)zy_lastLoadingUrl
{
    return objc_getAssociatedObject(self, &kLastLoadingUrlKey);
}

- (void)setZy_lastLoadingUrl:(NSURL *)url
{
    objc_setAssociatedObject(self, &kLastLoadingUrlKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (ZYTasksDictionary *)zy_taskDictionary
{
    @synchronized (self) {
        ZYTasksDictionary *Tasks = objc_getAssociatedObject(self, &kTasksDictKey);
        if (!Tasks) {
            Tasks = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory capacity:0];
            
            objc_setAssociatedObject(self, &kTasksDictKey, Tasks, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        }
        return Tasks;
    }
}

- (void)zy_externalSetImage:(NSString *)urlStr
                  completed:(ZYExternalCompletionBlock)completed
{
    if (!urlStr.length) {
        return;
    }
    NSURL *url = [NSURL URLWithString:urlStr];
    self.zy_lastLoadingUrl = url;
    
    //先取消上一个下载
    [self p_cancelLastLoading];
    
    @weakify(self)
    id<IZYTaskProtocol> task = [[ZYWebImageManager sharedManager]
                                loadImageWithUrlStr:urlStr
                                enableFailRetry:YES
                                completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, ZYImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
        @strongify(self)
        if (!self) {
            return;
        }
        completed ? completed(image, data, error, cacheType, finished, imageURL) : nil;
    }];
    [self zy_setImageLoadTask:task];
}

- (void)zy_setImageLoadTask:(id<IZYTaskProtocol>)task
{
    NSString *key = NSStringFromClass(self.class);
    if (task) {
        ZYTasksDictionary *tasksDict = self.zy_taskDictionary;
        @synchronized (self) {
            [tasksDict setObject:task forKey:key];
        }
    }
}

- (void)zy_externalCancelCurrentLoading
{
    NSString *key = NSStringFromClass(self.class);
    ZYTasksDictionary *tasksDict = self.zy_taskDictionary;
    id<IZYTaskProtocol> task = nil;
    @synchronized (self) {
        task = [tasksDict objectForKey:key];
    }
    if (task) {
        if ([task respondsToSelector:@selector(cancel)]) {
            [task cancel];
        }
        @synchronized (self) {
            [tasksDict removeObjectForKey:key];
        }
    }
}

- (void)p_cancelLastLoading
{
    [self zy_externalCancelCurrentLoading];
}
@end
